package com.lecyon.farm.service.impl;

import com.google.common.collect.Lists;
import com.lecyon.farm.base.RestResponse;
import com.lecyon.farm.entity.elasticsearch.WorkOutPoints;
import com.lecyon.farm.service.IWorkOutPointsService;
import com.lecyon.farm.util.StringHelper;
import com.lecyon.farm.vo.query.QueryWorkOutPointsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Yao Zheng
 * @Date 2020/4/19 12:21
 */
@Service
@Slf4j
public class WorkOutPointsServiceImpl implements IWorkOutPointsService {

    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 分页参数
     */
    private static final Integer pageNumber = 0;
    private static final Integer pageSize = 200;
    Pageable pageable = PageRequest.of(pageNumber, pageSize);

    /**
     * 保存地块外围点
     *
     * @param entity 设备状态明细
     * @return MongoEquipmentStatusDetail
     */
    @Override
    public RestResponse<WorkOutPoints> save(WorkOutPoints entity) {
        return null;
    }

    /**
     * 根据地块编号查询地块外围点唯一记录
     *
     * @param queryVo 查询条件（地块编号）
     * @return 地块外围点
     */
    @Override
    public WorkOutPoints getByWorkSerial(QueryWorkOutPointsVo queryVo) {
        WorkOutPoints result = null;
        List<WorkOutPoints> resultList = getList(queryVo);
        if (CollectionUtils.isNotEmpty(resultList)) {
            if (1 <= resultList.size()) {
                result = resultList.get(0);
            }
        }
        return result;
    }

    /**
     * 根据条件查询地块外围点
     *
     * @param queryVo 查询条件
     * @return 地块外围点
     */
    @Override
    public List<WorkOutPoints> getList(QueryWorkOutPointsVo queryVo) {
        String workSerial = queryVo.getWork_serial();
        String splitChar = "-";
        String queryCondition = workSerial;
        if (StringHelper.isNotEmpty(workSerial)) {
            if (workSerial.contains(splitChar)) {
                queryCondition = workSerial.substring(0, workSerial.indexOf(splitChar));
                log.info("workSerial : {}", queryCondition);
            }
        }
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchPhrasePrefixQuery("work_serial", queryCondition))
                .withPageable(pageable)
                .build();
        List<WorkOutPoints> resultList;
        resultList = elasticsearchTemplate.queryForList(searchQuery, WorkOutPoints.class);
        List<WorkOutPoints> result = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(resultList)) {
            for (WorkOutPoints entity : resultList) {
                if (StringHelper.isEmpty(entity.getWork_serial()) || !workSerial.equals(entity.getWork_serial())) {
                    log.warn("未命中 workOutPoints : {}, 需要的serial : {}", entity.getWork_serial(), workSerial);
                    continue;
                }
                if (StringHelper.isEmpty(entity.getGps()) || !entity.getGps().startsWith("[") || !entity.getGps().endsWith("]")) {
                    log.warn("GPS数据不合法 workOutPoints : {}", entity.getGps());
                    continue;
                }
                log.info("命中 workOutPoints : {}", entity.toString());
                result.add(entity);
            }
        }
        if (CollectionUtils.isNotEmpty(result)) {
            result = result.stream().distinct().collect(Collectors.toList());
            for (WorkOutPoints entity : result) {
                log.info(entity.toString());
            }
        }
        return result;
    }

    /**
     * ----------------------------- 分割线 以下是setter方法，用于替换field上的@Autowired -----------------------------
     */

    @Autowired
    @Lazy
    public void setElasticsearchTemplate(ElasticsearchTemplate elasticsearchTemplate) {
        this.elasticsearchTemplate = elasticsearchTemplate;
    }
}
